package com.google.gwt.sample.contacts.client.presenter;

import org.fusesource.restygwt.client.Method;
import org.fusesource.restygwt.client.MethodCallback;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.sample.contacts.client.ContactsResourceAsync;
import com.google.gwt.sample.contacts.client.event.ContactUpdatedEvent;
import com.google.gwt.sample.contacts.client.event.EditContactCancelledEvent;
import com.google.gwt.sample.contacts.client.view.EditContactViewDisplay;
import com.google.gwt.sample.contacts.shared.Contact;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HasWidgets;

public class EditContactPresenter implements Presenter {

	private Contact contact;
	private final HandlerManager eventBus;
	private final EditContactViewDisplay display;

	public EditContactPresenter(HandlerManager eventBus,
			EditContactViewDisplay display) {
		this.eventBus = eventBus;
		this.contact = new Contact();
		this.display = display;
		bind();
	}

	public EditContactPresenter(HandlerManager eventBus,
			EditContactViewDisplay display, String id) {
		this.eventBus = eventBus;
		this.display = display;

		bind();

		getContact(id);
	}

	private void getContact(String id) {
		ContactsResourceAsync.Util.get().getContact(id,
				new MethodCallback<Contact>() {

					@Override
					public void onFailure(Method method, Throwable exception) {
						Window.alert("Error retrieving contact! Cause: "
								+ exception.getMessage());
					}

					@Override
					public void onSuccess(Method method, Contact response) {
						contact = response;
						EditContactPresenter.this.display.getFirstName()
								.setValue(contact.getFirstName());
						EditContactPresenter.this.display.getLastName()
								.setValue(contact.getLastName());
						EditContactPresenter.this.display.getEmailAddress()
								.setValue(contact.getEmailAddress());
					}
				});

	}

	public void bind() {
		this.display.getSaveButton().addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				doSave();
			}
		});

		this.display.getCancelButton().addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				eventBus.fireEvent(new EditContactCancelledEvent());
			}
		});
	}

	public void go(final HasWidgets container) {
		container.clear();
		container.add(display.asWidget());
	}

	private void doSave() {
		contact.setFirstName(display.getFirstName().getValue());
		contact.setLastName(display.getLastName().getValue());
		contact.setEmailAddress(display.getEmailAddress().getValue());

		if (contact.getId() != null) {
			ContactsResourceAsync.Util.get().updateContact(contact,
					new MethodCallback<Contact>() {

						@Override
						public void onFailure(Method method, Throwable exception) {
							Window.alert("Error updating contact! Cause: "
									+ exception.getMessage());
						}

						@Override
						public void onSuccess(Method method, Contact response) {
							eventBus.fireEvent(new ContactUpdatedEvent(response));
						}
					});
		} else {
			ContactsResourceAsync.Util.get().addContact(contact,
					new MethodCallback<Contact>() {

						@Override
						public void onFailure(Method method, Throwable exception) {
							Window.alert("Error adding contact! Cause: "
									+ exception.getMessage());
						}

						@Override
						public void onSuccess(Method method, Contact response) {
							eventBus.fireEvent(new ContactUpdatedEvent(response));
						}
					});
		}

	}

}
